package com.eunion.core;

import java.io.IOException;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * Use Enum as a singleton.
 * 
 * @author Wang Minghao
 *
 */
@Component
public class JsonHelper {

    private static final Logger log = LoggerFactory.getLogger(JsonHelper.class);

    private final ObjectMapper mapper;

    public JsonHelper(ObjectMapper mapper) {
        super();
        this.mapper = mapper;
    }

    public String toJson(Object obj) throws JsonProcessingException {
        return toJson(obj, null);
    }

    public String toJson(Object obj, Class<?> viewClass) throws JsonProcessingException {
        if (obj == null) {
            log.warn("one null object tried to be jsoned!");
            return null;
        }
        return mapper.writerWithView(viewClass).writeValueAsString(obj);
    }

    public <T> T readFromMap(Map<?, ?> map, Class<T> targetClass) throws IOException {
        return fromJson(toJson(map), targetClass);
    }

    public <T> T fromJson(String json, Class<T> targetClass) throws IOException {
        return mapper.readValue(json, targetClass);
    }

    public <T> T fromJson(JsonParser parser, Class<T> targetClass) throws IOException {
        return mapper.readValue(parser, targetClass);
    }

    public <C, T> C fromJson(String json, Class<C> collectionType, Class<T> targetClass) throws IOException {
        return mapper.readValue(json, mapper.getTypeFactory().constructParametricType(collectionType, targetClass));
    }

    public <C, T> Map<C, T> fromJsonToRawMap(String json, Class<C> keyClass, Class<T> valueClass) throws IOException {
        return mapper.readValue(json, mapper.getTypeFactory().constructMapType(Map.class, keyClass, valueClass));
    }

}
